<template>
  <div class="dropdown" :class="[{open: opened}, clrPosition]" @click="clicked">
    <button class="dropdown-toggle btn" :class="toggleClass" type="button" @click.stop="toggleClicked">
        <slot name="toggle"></slot>
        <clr-icon-vue
          shape="caret"
          :dir="subordinate ? 'right' : opened ? 'up' : 'down'">
        </clr-icon-vue>
      </button>
    <div class="dropdown-menu" v-show="opened" @click="itemClicked">
      <slot :clickedItem="clickedItem" :opened="opened"></slot>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import { hyphenate } from "../../js/utils";

// declare module "vue/types/vue" {
//   interface Vue {
//     clickedItem: any;
//   }
// }

@Component({})
export default class ClrDropdown extends Vue {
  @Prop({ default: "bottom-left", required: true })
  private position: string;
  @Prop({ default: "true" })
  private closeOnItemClick: boolean;
  @Prop({ default: "true" })
  private closeOnOutsideClick: boolean;
  @Prop({ default: "true", type: Boolean })
  private opened: boolean;

  @Prop() private toggleClass: string;

  clickedItem = null;

  get clrPosition() {
    let position = hyphenate(this.position);
    let availablePositions = [
      "bottom-left",
      "bottom-right",
      "top-left",
      "top-right",
      "left-bottom",
      "left-top",
      "right-bottom",
      "right-top"
    ];

    return !this.subordinate
      ? availablePositions.indexOf(position) > -1 ? position : "bottom-left"
      : availablePositions.indexOf(position) > 3 ? position : "right-top";
  }

  get subordinate() {
    return this.$parent && this.$parent.$options.name === this.$options.name;
  }

  updateOpened(val) {
    this.$emit("update:opened", val);
  }

  close() {
    this.updateOpened(false);
  }
  clicked(ev) {
    if (!this.closeOnItemClick || !this.subordinate) {
      ev.stopPropagation();
    }
  }
  toggleClicked() {
    if (this.subordinate) {
      const $parent: any = this.$parent;
      $parent.clickedItem = this;
    }
    this.updateOpened(!this.opened);
  }
  itemClicked() {
    this.clickedItem = "Line Item";
    this.closeOnItemClick && this.close();
  }

  @Watch("opened")
  onChangeOpended(val) {
    if (val) {
      this.clickedItem = undefined;
    }
  }
  @Watch("siblingClicked")
  onChangeSiblingClicked(val) {
    if (val !== this && this.opened) {
      this.close();
    }
  }

  @Watch("parentOpened")
  onChangeParentOpened(val) {
    if (!val && this.opened) {
      this.close();
    }
  }

  created() {
    if (this.closeOnOutsideClick) {
      document.addEventListener("click", this.close);
    }
  }
  destroyed() {
    if (this.closeOnOutsideClick) {
      document.removeEventListener("click", this.close);
    }
  }
}
</script>

<style scoped>
.dropdown-toggle.btn-link:focus,
.dropdown-toggle.btn-outline:focus,
.dropdown-toggle[class*="btn-outline-"]:focus {
  outline: none;
}
</style>
